"""
码将 - 密码学麻将游戏规则引擎
实现密码学特殊组合的识别和计分系统
"""

from tile import *

class CryptoScoring:
    """密码学组合计分系统"""
    
    def __init__(self):
        # 基础组合分数
        self.base_scores = {
            'triplet': 2,    # 基础刻子
            'sequence': 1,   # 基础顺子
            'pair': 1,       # 基础对子
            'kong': 4        # 基础杠子
        }
        
        # 特殊组合分数
        self.special_scores = {
            'complete_encryption': 8,      # 完整加密流程
            'digital_signature': 10,       # 数字签名系统
            'hash_verification': 6,        # 哈希验证系统
            'key_exchange': 12,            # 密钥交换协议
            'post_quantum': 15,            # 抗量子加密
            'quantum_attack': -5,          # 量子攻击（负分）
            'broken_crypto': -10,          # 被破解的密码（负分）
            'defense_bonus': 3             # 防御成功奖励
        }

    def check_complete_encryption(self, tiles):
        """检查完整加密流程组合"""
        # 明文 + 对称/非对称加密 + 密钥
        has_plaintext = any(t.kind == 'T' and t.n == 1 for t in tiles)  # 明文
        has_key = any(t.kind == 'T' and t.n == 3 for t in tiles)  # 密钥
        has_encryption = any(t.kind in ['S', 'A'] for t in tiles)  # 加密算法
        
        if has_plaintext and has_key and has_encryption:
            return self.special_scores['complete_encryption']
        return 0

    def check_digital_signature(self, tiles):
        """检查数字签名系统组合"""
        # 数字签名系统：明文/密文 + 非对称加密 + 数字签名 + 证书
        has_text = any(t.kind == 'T' and t.n in [1, 2] for t in tiles)  # 明文或密文
        has_asymmetric = any(t.kind == 'A' for t in tiles)  # 非对称加密
        has_signature = any(t.kind == 'T' and t.n == 4 for t in tiles)  # 数字签名
        has_certificate = any(t.kind == 'T' and t.n == 5 for t in tiles)  # 证书
        
        if has_text and has_asymmetric and has_signature:
            score = self.special_scores['digital_signature']
            if has_certificate:
                score += 2  # 完整PKI系统额外奖励
            return score
        return 0

    def check_hash_verification(self, tiles):
        """检查哈希验证系统组合"""
        # 哈希验证：密文/明文 + 哈希函数 + 盐值/随机数
        has_text = any(t.kind == 'T' and t.n in [1, 2] for t in tiles)  # 明文或密文
        has_hash = any(t.kind == 'H' for t in tiles)  # 哈希函数
        has_salt_or_random = any(t.kind == 'T' and t.n in [6, 7] for t in tiles)  # 盐值或随机数
        
        if has_text and has_hash and has_salt_or_random:
            return self.special_scores['hash_verification']
        return 0

    def check_key_exchange(self, tiles):
        """检查密钥交换协议组合"""
        # 密钥交换：两张不同的非对称加密 + 密钥 + 随机数
        asymmetric_tiles = [t for t in tiles if t.kind == 'A']
        has_key = any(t.kind == 'T' and t.n == 3 for t in tiles)  # 密钥
        has_random = any(t.kind == 'T' and t.n == 7 for t in tiles)  # 随机数
        
        # 检查是否有两张不同的非对称加密算法
        unique_asymmetric = set(t.n for t in asymmetric_tiles)
        if len(unique_asymmetric) >= 2 and has_key and has_random:
            return self.special_scores['key_exchange']
        return 0

    def check_post_quantum(self, tiles):
        """检查抗量子加密组合"""
        post_quantum_tiles = [t for t in tiles if hasattr(t, 'is_post_quantum') and t.is_post_quantum]
        has_random = any(t.kind == 'T' and t.n == 7 for t in tiles)  # 随机数
        has_key = any(t.kind == 'T' and t.n == 3 for t in tiles)  # 密钥
        
        # 方案1：后量子算法 + 随机数 + 密钥
        if len(post_quantum_tiles) >= 1 and has_random and has_key:
            return self.special_scores['post_quantum']
        
        # 方案2：任意3张后量子算法
        if len(post_quantum_tiles) >= 3:
            return self.special_scores['post_quantum']
        
        return 0

    def check_quantum_attack(self, tiles, quantum_tiles):
        """检查量子攻击场景"""
        # 攻击者 + 任意两张算法（负分组合）
        has_attacker = any(t.kind == 'T' and t.n == 8 for t in tiles)  # 攻击者
        crypto_tiles = [t for t in tiles if t.kind in ['S', 'A', 'H']]
        
        if has_attacker and len(crypto_tiles) >= 2:
            return self.special_scores['quantum_attack']
        
        # 量子计算机破解经典算法
        for quantum in quantum_tiles:
            if hasattr(quantum, 'can_break'):
                broken_tiles = [t for t in tiles if quantum.can_break(t)]
                if broken_tiles:
                    return self.special_scores['broken_crypto']
        
        return 0

    def calculate_crypto_bonus(self, player_tiles, quantum_tiles=[]):
        """计算密码学特殊组合的总分"""
        total_bonus = 0
        
        # 检查各种特殊组合
        total_bonus += self.check_complete_encryption(player_tiles)
        total_bonus += self.check_digital_signature(player_tiles)
        total_bonus += self.check_hash_verification(player_tiles)
        total_bonus += self.check_key_exchange(player_tiles)
        total_bonus += self.check_post_quantum(player_tiles)
        
        # 检查攻击场景（可能扣分）
        attack_penalty = self.check_quantum_attack(player_tiles, quantum_tiles)
        total_bonus += attack_penalty
        
        return total_bonus

    def check_compatibility(self, tiles):
        """检查算法兼容性"""
        # MD5 + SHA-1 不能同时存在于一个有效组合中
        has_md5 = any(t.kind == 'H' and t.n == 1 for t in tiles)
        has_sha1 = any(t.kind == 'H' and t.n == 2 for t in tiles)
        
        if has_md5 and has_sha1:
            return False, "MD5和SHA-1存在兼容性问题"
        
        return True, ""

    def check_security_evolution(self, old_tiles, new_tile):
        """检查安全算法的时间线演进"""
        # 高级算法可以"淘汰"低级算法
        if new_tile.kind in ['S', 'A', 'H'] and new_tile.n >= 8:
            # 8-9级算法可以替换1-3级算法
            replaced_tiles = [t for t in old_tiles 
                            if t.kind == new_tile.kind and t.n <= 3]
            return replaced_tiles
        return []

    def get_tile_info(self, tile):
        """获取牌的详细信息"""
        info = {
            'name': tile.text,
            'kind': tile.kind,
            'security_level': getattr(tile, 'security_level', 0),
            'year_invented': getattr(tile, 'year_invented', 0),
            'key_length': getattr(tile, 'key_length', ''),
            'application': getattr(tile, 'application', ''),
            'is_post_quantum': getattr(tile, 'is_post_quantum', False)
        }
        return info


class CryptoWinConditions:
    """码将胜利条件检查"""
    
    def __init__(self):
        self.scoring = CryptoScoring()
    
    def check_standard_win(self, tiles):
        """标准胜利：组成4个基础组合 + 1个配对，总分达到30分以上"""
        # 这里应该调用传统的破解判断逻辑
        # 然后检查总分是否达到30分
        total_score = self.scoring.calculate_crypto_bonus(tiles)
        return total_score >= 30
    
    def check_pki_system_win(self, tiles):
        """完整PKI系统胜利"""
        has_certificate = any(t.kind == 'T' and t.n == 5 for t in tiles)  # 证书
        has_signature = any(t.kind == 'T' and t.n == 4 for t in tiles)  # 数字签名
        has_asymmetric = any(t.kind == 'A' for t in tiles)  # 非对称加密
        has_hash = any(t.kind == 'H' for t in tiles)  # 哈希函数
        
        return has_certificate and has_signature and has_asymmetric and has_hash
    
    def check_perfect_forward_secrecy_win(self, tiles):
        """完美前向保密胜利"""
        # 密钥交换 + 对称加密 + 随机数 + 哈希验证
        has_key_exchange = self.scoring.check_key_exchange(tiles) > 0
        has_symmetric = any(t.kind == 'S' for t in tiles)  # 对称加密
        has_random = any(t.kind == 'T' and t.n == 7 for t in tiles)  # 随机数
        has_hash_verification = self.scoring.check_hash_verification(tiles) > 0
        
        return has_key_exchange and has_symmetric and has_random and has_hash_verification
    
    def check_post_quantum_defense_win(self, tiles):
        """抗量子防御胜利"""
        # 集齐3种不同的后量子算法
        post_quantum_types = set()
        for tile in tiles:
            if hasattr(tile, 'is_post_quantum') and tile.is_post_quantum:
                post_quantum_types.add(tile.kind)
        
        return len(post_quantum_types) >= 3
    
    def check_instant_win(self, tiles):
        """即时胜利条件"""
        # 同时拥有完整的加密、签名、验证三套系统
        has_encryption = self.scoring.check_complete_encryption(tiles) > 0
        has_signature = self.scoring.check_digital_signature(tiles) > 0
        has_verification = self.scoring.check_hash_verification(tiles) > 0
        
        return has_encryption and has_signature and has_verification 